#include <string.h>
#include <stdio.h>
#include <linux/kernel.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/sched.h>
#include <semaphore.h>
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */ 
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
  #include <sys/types.h>
  #include <sys/wait.h>
  #include <unistd.h>
  #include <stdio.h>
  #include <stdlib.h>
  
long count=0;

struct sched_param {
	int sched_priority;
};

void signal_callback_handler(int signum){
	pid_t pid;
	int weight=0;
	
	pid = gettid();
	weight = syscall(368,getpid());
	printf("%d:%d:%d\n",pid, weight, count);
	alarm(1);
	return;
}


int main(int argc, char *argv[]){
	pid_t pid,pid0,pid1;
	struct sched_param mParam;
	int mPolicy=-1;
	int mPolicy0=-1;
	int mPolicy1=-1;
	int status;
	
	sem_t *sem_c;
	sem_t *sem_p;
        int oflag = O_CREAT;
        mode_t mode = 0644;
        unsigned int value = 0;

	pid = getpid();
	syscall(368,pid);
	mParam.sched_priority = 90;//for real-time should be 1-99
	sched_setscheduler(pid, 6, &mParam);
//	mPolicy = sched_getscheduler(1);
//	syscall(368,pid);
//printf("parent [%d] cur policies:%d, weight:\n",pid,mPolicy,syscall(368,pid));

	signal(SIGALRM, signal_callback_handler);

        sem_c = sem_open("sem_c", oflag, mode, value);
	sem_p = sem_open("sem_p", oflag, mode, value);

	//sem_init(&sem_c, 1, 0);
	//sem_init(&sem_p, 1, 0);
	if(!(pid0=fork())){
		//child 0
		sem_post(sem_p);
		sem_wait(sem_c);
		sem_post(sem_c);

		pid0 = getpid();
		syscall(367,pid0,10);
//		mPolicy0 = sched_getscheduler(pid0);
//printf("[%d] cur policies:%d, weight:%d\n",pid0,mPolicy0,syscall(368,pid0));
		alarm(1);
		while(count!=1000000000){
			count++;
		}
		return 0;
	}else{
		//parent
		if(!(pid1=fork())){
			//child 1
			sem_post(sem_p);
			sem_wait(sem_c);
			sem_post(sem_c);

			pid1 = getpid();
			syscall(367,pid1,5);
//			mPolicy1 = sched_getscheduler(pid1);
//printf("[%d] cur policies:%d, weight:%d\n",pid1,mPolicy1,syscall(368,pid1));
			alarm(1);
			while(count!=1000000000){
				count++;
			}
			return 0;
		}else{
			//parent
			sem_wait(sem_p);
			sem_wait(sem_p);
			sem_post(sem_c);
			sem_post(sem_c);
		}
	}

	if ((pid = wait(&status)) == -1){
		exit(-1);
	}else{
		if ((pid = wait(&status)) == -1){
			exit(-1);
		}else{
			exit(EXIT_SUCCESS);
		}
	}


}
//The weight of a task and the SCHED_WRR scheduling flag should be inherited by the child of any forking task.
//If a process' scheduler is set to SCHED_WRR after previously being set to another scheduler, its weight should be the default weight.




